﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using Sora.HelpSystem.Package;
using System.IO;
using System.ComponentModel;
using Sora.HelpSystem.UI.WPF;
using Sora.HelpSystem.Package.Pages;

namespace Sora.HelpSystem.Viewer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public HelpDocument Document { get; private set; }

        public MainWindow()
        {
            string fileName = String.Empty;

            if (App.ApplicationArguments != null && App.ApplicationArguments.Length >= 1)
                fileName = App.ApplicationArguments[0];

            if (String.IsNullOrEmpty(fileName))
            {
                var dlg = new OpenFileDialog();
                dlg.Filter = "Help File (*.dshelp)|*.dshelp|All Files|*.*";

                if (dlg.ShowDialog() == true)
                {
                    fileName = dlg.FileName;
                }
                else
                    fileName = null;
            }

            if (String.IsNullOrEmpty(fileName))
                Environment.Exit(0);
            else if (!File.Exists(fileName))
            {
                MessageBox.Show(String.Format("The file {0} was not found", fileName));
            }
            else
            {
                try
                {
                    Document = new HelpDocument(fileName, true, false);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    Environment.Exit(0);
                }
            }

            DisableSummaryChangeEvent = false;

            InitializeComponent();

            helpSummary.SelectedUriChanged += SummarySelectedUriChanged;
            
            DependencyPropertyDescriptor.FromProperty(HelpContentDisplay.CurrentPageUriProperty, typeof(HelpContentDisplay)).AddValueChanged(helpContent, ContentCurrentPageUriPropertyChanged);
            DependencyPropertyDescriptor.FromProperty(HelpContentDisplay.CurrentPageTitleProperty.DependencyProperty, typeof(HelpContentDisplay)).AddValueChanged(helpContent, ContentCurrentPageTitlePropertyChanged);
            DependencyPropertyDescriptor.FromProperty(HelpContentDisplay.CurrentHelpPageProperty.DependencyProperty, typeof(HelpContentDisplay)).AddValueChanged(helpContent, ContentCurrentHelpPagePropertyChanged);

            helpHeader.CurrentPageUri = new Uri(Document.DocumentBaseUri + "/header");
            goHome_Click(null, null);
        }

        private bool DisableSummaryChangeEvent { get; set; }

        private void ContentCurrentHelpPagePropertyChanged(object sender, EventArgs e)
        {
            DisableSummaryChangeEvent = true;
            try
            {
                helpSummary.SelectItem(helpContent.CurrentHelpPage);
            }
            finally
            {
                DisableSummaryChangeEvent = false;
            }
        }

        private void ContentCurrentPageTitlePropertyChanged(object sender, EventArgs e)
        {
            Title = String.Format("{0} - Sora Help Viewer", helpContent.CurrentPageTitle);
        }

        private void ContentCurrentPageUriPropertyChanged(object sender, EventArgs e)
        {
            _currentDocumentUri = helpContent.CurrentPageUri;

            NotifyCurrentUriChange();
        }

        private void SummarySelectedUriChanged(object sender, EventArgs e)
        {
            if (!DisableSummaryChangeEvent)
                NavigateToTarget(helpSummary.SelectedUri);
        }

        private void NavigateToTarget(Uri navigationTarget)
        {
            _currentDocumentUri = navigationTarget;

            NotifyCurrentUriChange();
        }

        private Uri _currentDocumentUri;

        public Uri CurrentDocumentUri
        {
            get { return _currentDocumentUri; }
            set
            {
                _currentDocumentUri = value;

                NotifyCurrentUriChange();
            }
        }

        private void NotifyCurrentUriChange()
        {
            uriTextBox.Text = _currentDocumentUri.AbsoluteUri;

            RaisePropertyChanged("CurrentDocumentUri");
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

        #endregion

        private void GoExecute()
        {
            NavigateToTarget(new Uri(uriTextBox.Text));
        }

        private void uriTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                GoExecute();
            }
        }

        private void goPrev_Click(object sender, RoutedEventArgs e)
        {
            helpContent.HistoryGoBack();
        }

        private void goNext_Click(object sender, RoutedEventArgs e)
        {
            helpContent.HistoryGoNext();
        }

        private void goHome_Click(object sender, RoutedEventArgs e)
        {
            CurrentDocumentUri = Document.StartPageUri;
        }

        private void goExecute_Click(object sender, RoutedEventArgs e)
        {
            GoExecute();
        }

        private void goCancel_Click(object sender, RoutedEventArgs e)
        {
            helpContent.Stop();
        }

        private void goSearch_Click(object sender, RoutedEventArgs e)
        {
            if (!String.IsNullOrEmpty(searchBox.Text))
            {
                var searchQuery = searchBox.Text
                    .Replace("/", "")
                    .Replace("\\", "")
                    .Replace(":", "")
                    .Replace("*", "")
                    .Replace("?", "")
                    .Replace("\"", "");

                var parts = searchQuery.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                searchQuery = String.Empty;

                for (int i = 0; i < parts.Length; i++)
                {
                    searchQuery += parts[i];

                    if (i + 1 < parts.Length)
                        searchQuery += "+";
                }

                if (!String.IsNullOrEmpty(searchQuery))
                {
                    searchQuery = Document.DocumentBaseUri.AbsoluteUri + "/search?" + searchQuery;

                    NavigateToTarget(new Uri(searchQuery));
                }
            }
        }

        private void searchBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
                goSearch_Click(null, null);
        }
    }
}
